package com.quwan.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.lang.management.ManagementFactory;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.IntStream;

public class DateUtils extends org.apache.commons.lang3.time.DateUtils {

    public static String YYYY_MM_DD = "yyyy-MM-dd";

    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
    public static String HH_MM_SS = "HH:mm:ss";
    public static String HH_MM = "HH:mm";
    public static String MM_DD_HH_MM = "MM-dd HH:mm";

    private static String[] parsePatterns = {
            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};


    public static LocalDateTime localDateTimeOfStr(String localDateTime) {
        if (StringUtils.isBlank(localDateTime))
            return null;
        return LocalDateTime.parse(localDateTime.length() > 19 ? localDateTime.substring(0, 19) : localDateTime, DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));
    }

    public static LocalDate localDateOfStr(String localDate) {
        return LocalDate.parse(localDate, DateTimeFormatter.ofPattern(YYYY_MM_DD));
    }

    public static String date2Str(Date date) {
        return new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS).format(date);
    }

    /**
     * 获取当前Date型日期
     *
     * @return Date() 当前日期
     */
    public static Date getNowDate() {
        return new Date();
    }

    /**
     * 获取当前日期, 默认格式为yyyy-MM-dd
     *
     * @return String
     */
    public static String getDate() {
        return dateTimeNow(YYYY_MM_DD);
    }

    public static final String getLocalDateStr() {
        return LocalDate.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD));
    }

    public static final String getLocalDateStr(LocalDate date) {
        if (date == null)
            return "";
        return date.format(DateTimeFormatter.ofPattern(YYYY_MM_DD));
    }

    public static final String getLocalTimeStr() {
        return LocalTime.now().format(DateTimeFormatter.ofPattern(HH_MM_SS));
    }


    public static final String getLocalTimeStr(LocalTime time) {
        return time.format(DateTimeFormatter.ofPattern(HH_MM_SS));
    }

    public static final String getLocalDateTimeStr(LocalDateTime dateTime) {
        return dateTime.format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));
    }

    public static final String getLocalDateTimeStr(LocalDateTime dateTime, String pattern) {
        return Optional.ofNullable(dateTime).map(date -> dateTime.format(DateTimeFormatter.ofPattern(pattern))).orElse("");
        // return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static final String getLocalDateTimeStr() {
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));
    }


    public static final String getTime() {
        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
    }

    public static final String dateTimeNow() {
        return dateTimeNow(YYYYMMDDHHMMSS);
    }

    public static final String dateTimeNow(final String format) {
        return parseDateToStr(format, new Date());
    }

    public static final String dateTime(final Date date) {
        return parseDateToStr(YYYY_MM_DD, date);
    }

    public static final String parseDateToStr(final String format, final Date date) {
        return new SimpleDateFormat(format).format(date);
    }

    public static final Date dateTime(final String format, final String ts) {
        try {
            return new SimpleDateFormat(format).parse(ts);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 日期路径 即年/月/日 如2016/05/05
     */
    public static final String datePath() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyy/MM/dd");
    }

    /**
     * 日期路径 即年/月/日 如20180808
     */
    public static final String dateTime() {
        Date now = new Date();
        return DateFormatUtils.format(now, "yyyyMMdd");
    }

    /**
     * 日期型字符串转化为日期 格式
     */
    public static Date parseDate(Object str) {
        if (str == null) {
            return null;
        }
        try {
            return parseDate(str.toString(), parsePatterns);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取服务器启动时间
     */
    public static Date getServerStartDate() {
        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
        return new Date(time);
    }

    /**
     * 计算相差天数
     */
    public static int differentDaysByMillisecond(Date date1, Date date2) {
        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
    }

    /**
     * 计算两个时间差
     */
    public static String getDatePoor(Date endDate, Date nowDate) {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endDate.getTime() - nowDate.getTime();
        // 计算差多少天
        long day = diff / nd;
        // 计算差多少小时
        long hour = diff % nd / nh;
        // 计算差多少分钟
        long min = diff % nd % nh / nm;
        // 计算差多少秒//输出结果
        // long sec = diff % nd % nh % nm / ns;
        return day + "天" + hour + "小时" + min + "分钟";
    }

    public static String format(Date date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        return sdf.format(date);
    }

    public static String dateyyyyMMdd() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
        return sdf.format(new Date());
    }

    public static Date str2Date(String str) {
        LocalDateTime parse = LocalDateTime.parse(str.substring(0, 19), DateTimeFormatter.ofPattern(YYYY_MM_DD_HH_MM_SS));
        return Date.from(parse.atZone(ZoneId.systemDefault()).toInstant());

    }


    public static LocalTime localTimeOfStr(String localTime) {
        return LocalTime.parse(localTime, DateTimeFormatter.ofPattern(HH_MM));

    }

    public static String getDateStrFromWeek(String week) {
        return null;
    }

    /**
     * 当前时间 往后7天的 星期：日期
     *
     * @return key = week value = date
     */
    public static Map<String, String> week_DateMap() {
        LocalDate now = LocalDate.now();
        Map<String, String> map = new HashMap<>();
        IntStream.range(0, 7).forEach(i -> {
            String week = now.plusDays(i).getDayOfWeek().getValue() + "";
            map.put(week, getLocalDateStr(now.plusDays(i)));
        });
        return map;
    }


    /**
     * 时间加减几天
     *
     * @param date
     * @param index
     * @return
     */
    public static final Date getDatePlus(Date date, int index) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);//设置起时间
        cal.add(Calendar.DATE, index);
        return cal.getTime();
    }

    /**
     * 计算开始时间到结束时间 相差的秒数
     *
     * @param start
     * @param end
     * @return
     */
    public static Long computeSecond(LocalDateTime start, LocalDateTime end) {
        long minutes = Duration.between(start, end).toMinutes();
        return minutes * 60;
    }

    public static Long computeMinutes(LocalDateTime start, LocalDateTime end) {
        return Duration.between(start, end).toMinutes();

    }

    public static String computeOnlineTime(LocalDateTime timeSecond) {
        Long nowSeconds = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
        Long time = timeSecond.toEpochSecond(ZoneOffset.of("+8"));
        String minuteStr = "分钟前";
        String hoursStr = "小时前";
        String dayStr = "天前";

        long minute = 60;
        long hours = 3600;
        long day = 86400;

        long second = nowSeconds - time;
        if (second < minute)
            return "刚刚";
        else if (second < hours)
            return second / minute + minuteStr;
        else if (second < day)
            return second / hours + hoursStr;
        else {
            long dayNum = second / day;

            if (dayNum > 7) dayNum = 7;
            return dayNum + dayStr;
        }
    }

//    public static String computeOnlineTime(LocalDateTime time) {
//        LocalDateTime now = LocalDateTime.now();
//        Long minutes = Duration.between(time, now).toMinutes();
//        if (minutes <= 3)
//            return "刚刚";
//        else if (minutes >= 5 && minutes < 15)
//            return "3分钟前";
//        else if (minutes >= 15 && minutes < 30)
//            return "15分钟前";
//        else if (minutes >= 30 && minutes < 60)
//            return "30分钟前";
//        else if (minutes >= 60 && minutes < 120)
//            return "1小时前";
//        else if (minutes >= 120 && minutes < 240)
//            return "2小时前";
//        else if (minutes >= 240 && minutes < 360)
//            return "4小时前";
//        else if (minutes >= 360 && minutes < 1440)
//            return "6小时前";
//        else if (minutes >= 1440 && minutes < 2880)
//            return "1天前";
//        else if (minutes >= 2880 && minutes < 4320)
//            return "2天前";
//        else if (minutes >= 4320 && minutes < 5760)
//            return "3天前";
//        else if (minutes >= 5760 && minutes < 7200)
//            return "4天前";
//        else if (minutes >= 7200 && minutes < 8640)
//            return "5天前";
//        else if (minutes >= 8640 && minutes < 10080)
//            return "6天前";
//        else
//            return "7天前";
//    }


    /**
     * 计算年份 和星座
     *
     * @param identity
     * @return return  year 年份 constellation -星座
     */
    public static Map<String, String> computeYearAndConstellation(String identity) {
        Map<String, String> ret = new HashMap<>();
        if (StringUtils.isBlank(identity) || identity.length() < 17)
            return ret;
        String birthday = identity.substring(6, 14);
        String year = birthday.substring(2, 3) + "0后";
        Integer month = Parse.toInt(birthday.substring(4), 101);
        String constellation = "";
        if (month >= 321 && month <= 419)
            constellation = "牡羊座";
        else if (month >= 420 && month <= 520)
            constellation = "金牛座";
        else if (month >= 521 && month <= 621)
            constellation = "金牛座";
        else if (month >= 521 && month <= 621)
            constellation = "双子座";
        else if (month >= 622 && month <= 722)
            constellation = "巨蟹座";
        else if (month >= 723 && month <= 822)
            constellation = "狮子座";
        else if (month >= 823 && month <= 922)
            constellation = "处女座";
        else if (month >= 923 && month <= 1023)
            constellation = "天平座";
        else if (month >= 1024 && month <= 1122)
            constellation = "天蝎座";
        else if (month >= 1123 && month <= 1221)
            constellation = "人马座";
        else if (month >= 120 && month <= 218)
            constellation = "宝瓶座";
        else if (month >= 219 && month <= 320)
            constellation = "双鱼座";
        else if (month >= 1222 || month <= 119)
            constellation = "山羊座";
        ret.put("year", year);
        ret.put("constellation", constellation);
        return ret;

    }
}
